package org.wx.io.netty.chart.client;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: wangxun
 * @createDate: 2021/2/18
 * @version: 1.0
 */
@Slf4j
public class ChartClientHandler extends ChannelInboundHandlerAdapter {

    static final String HEART_BEAT = "PING";
    static final String HEART_BEAT_ECHO = "PONG";
    private NettyChartClient client = new NettyChartClient();

    /**
     * 服务端发送消息
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        ByteBuf buf = (ByteBuf) msg;
        String content = buf.toString(Charset.forName("utf-8"));
        if(HEART_BEAT_ECHO.equals(content)){
            log.info("收到心跳回复..");
        }else{
            log.info(content);

        }

    }

    /**
     * 发送异常
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("exceptionCaught"+cause.toString());
        ctx.channel().eventLoop().schedule(new Runnable() {
            @Override
            public void run() {
                log.info("断线重新连接...");
                client.doConnect("127.0.0.1",9000);
            }
        }, 10, TimeUnit.SECONDS);
    }

    /**
     * 心跳检测，发送数据包
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof IdleStateEvent){
            IdleStateEvent event = (IdleStateEvent) evt;
            switch (event.state()){
                case READER_IDLE:
                    log.info("很长时间没有收到服务器回复，自动断线");
                    ctx.close();
                    break;
                case WRITER_IDLE:
                    log.info("未向服务器发送消息... 现在开始发送心跳");
                    ctx.writeAndFlush(Unpooled.copiedBuffer(HEART_BEAT,Charset.forName("utf-8")));
                    break;
                case ALL_IDLE:

                    break;
            }

        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ctx.channel().eventLoop().schedule(new Runnable() {
            @Override
            public void run() {
                log.info("断线重新连接...");
                client.doConnect("127.0.0.1",9000);
            }
        }, 10, TimeUnit.SECONDS);
    }
}
